package com.zenithmind.library.pojo.domain;

import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zenithmind.common.base.BaseEntity;
import com.zenithmind.library.enums.BorrowStatus;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 借阅记录实体
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(name = "借阅记录实体", description = "图书借阅记录信息")
@TableName("lib_borrow_record")
public class BorrowRecord extends BaseEntity {

    @NotNull(message = "用户ID不能为空")
    @Schema(description = "借阅用户ID")
    private String userId;

    @NotNull(message = "图书副本ID不能为空")
    @Schema(description = "图书副本ID")
    private String bookCopyId;

    @NotNull(message = "图书ID不能为空")
    @Schema(description = "图书ID")
    private String bookId;

    @Schema(description = "借阅日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate borrowDate;

    @Schema(description = "应还日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate dueDate;

    @Schema(description = "实际归还日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate returnDate;

    @Schema(description = "借阅状态")
    private Integer status;

    @Schema(description = "续借次数")
    private Integer renewalCount;

    @Schema(description = "最大续借次数")
    private Integer maxRenewalCount;

    @Schema(description = "逾期天数")
    private Integer overdueDays;

    @Schema(description = "罚金金额")
    private BigDecimal fineAmount;

    @Schema(description = "是否已支付罚金 (0-否, 1-是)")
    private Integer finePaid;

    @Schema(description = "借阅操作员ID")
    private String borrowOperatorId;

    @Schema(description = "归还操作员ID")
    private String returnOperatorId;

    @Schema(description = "借阅备注")
    @Size(max = 500, message = "借阅备注长度不能超过500个字符")
    private String borrowRemarks;

    @Schema(description = "归还备注")
    @Size(max = 500, message = "归还备注长度不能超过500个字符")
    private String returnRemarks;

    @Schema(description = "提醒次数")
    private Integer reminderCount;

    @Schema(description = "最后提醒时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime lastReminderTime;

    /**
     * 获取借阅状态枚举
     */
    public BorrowStatus getBorrowStatus() {
        return BorrowStatus.getByCode(this.status);
    }

    /**
     * 设置借阅状态枚举
     */
    public void setBorrowStatus(BorrowStatus borrowStatus) {
        this.status = borrowStatus != null ? borrowStatus.getCode() : null;
    }

    /**
     * 判断是否逾期
     */
    public boolean isOverdue() {
        if (returnDate != null) {
            return false; // 已归还
        }
        return dueDate != null && LocalDate.now().isAfter(dueDate);
    }

    /**
     * 计算逾期天数
     */
    public int calculateOverdueDays() {
        if (!isOverdue()) {
            return 0;
        }
        return (int) java.time.temporal.ChronoUnit.DAYS.between(dueDate, LocalDate.now());
    }

    /**
     * 判断是否可以续借
     */
    public boolean canRenew() {
        BorrowStatus borrowStatus = getBorrowStatus();
        return borrowStatus != null && 
               borrowStatus.isBorrowing() && 
               (renewalCount == null || renewalCount < maxRenewalCount) &&
               !isOverdue();
    }
}
